#include "resourceallocator.h"
#include <QDebug>
#include "Prerequisites.hpp"

template<> ResourceAllocator* Singleton<ResourceAllocator>::msSingleton = 0;
ResourceAllocator* ResourceAllocator::getSingletonPtr(void)
{
    return msSingleton;
}
ResourceAllocator& ResourceAllocator::getSingleton(void)
{
    assert( msSingleton );  return ( *msSingleton );
}
ResourceAllocator::ResourceAllocator()
{
    lastResourceId=0;
}
ResourceAllocator::~ResourceAllocator()
{
}
//-----------------------------------------------------------------------
void ResourceAllocator::askForResource(String askedFor, int askerId)
{
    Planner::getSingleton().blockProcess(askerId);
    bool foundFreeR=false;
    bool foundAtAll=false;
    for (resourceListIterator it = resourceList.begin(); it != resourceList.end(); ++it){
        if (((*it)->name == askedFor)&&(!((*it)->inUse))){
            (*it)->addToWaitingList(askerId);
            foundFreeR=true;
            break;
        }
    };
    if (!(foundFreeR)){
        for (resourceListIterator it = resourceList.begin(); it != resourceList.end(); ++it){
            if ((*it)->name == askedFor){
                (*it)->addToWaitingList(askerId);
                foundAtAll=true;
                break;
            }
        }
    };
    if ((!foundAtAll)&&(!foundFreeR)){
        processWoutR waitingProcess;
        waitingProcess.process=askerId;
        waitingProcess.resource=askedFor;
        waitingProcesses.push_back(waitingProcess);
        //qDebug() << askedFor;
    }
    giveResource();
    Planner::getSingleton().plan();
}
void ResourceAllocator::addResource(Resource* newR){
    if (newR->inUse){
        newR->addToWaitingList(-1);
    };
    resourceList.push_back(newR);
    giveResource();
}
Resource* ResourceAllocator::getResource(String usedR){
    for (resourceListIterator it = resourceList.begin(); it != resourceList.end(); ++it){
        if (usedR==(*it)->name){
            return((*it));
            break;
        }
   }
}
void ResourceAllocator::freeResource(Resource* usedR){
   usedR->inUse=false;
   usedR->removeFromWaitingList();
   giveResource();
   Planner::getSingleton().plan();
}
void ResourceAllocator::destroyResource(Resource* usedR){
    qDebug() << "aaaaaaa";
    /*
    for (intListIterator it = usedR->waitingList.begin(); it != usedR->waitingList.end(); ++it)
        {
           Planner::getSingleton().activateProcess(*it);
        }
        */
    for (resourceListIterator it = resourceList.begin(); it != resourceList.end(); ++it) {
        if ((*it)->resID==usedR->resID) {
            resourceList.erase(it);
            break;
        }
    }

   delete(usedR);
}
void ResourceAllocator::giveResource(){

    checkwaitingProcess();
    for (resourceListIterator it = resourceList.begin(); it != resourceList.end(); ++it)
        {
        //qDebug() << ">>>>:" << QString::fromStdString((*it)->name) << ((*it)->inUse) << ((*it)->waitingList.empty());
        if (!((*it)->inUse)){
            if (!((*it)->waitingList.empty()))
            {
                qDebug() << "----------------------------------->>>>:";
                qDebug() << "Atiduodamas resusas procesui:" <<((*it)->waitingList.front());
                Planner::getSingleton().giveResourceToProcess(((*it)->waitingList.front()),(*it));
                (*it)->inUse=true;
            }
        }
        }
}
int ResourceAllocator::giveNextResourceId(){
    lastResourceId++;
    return(lastResourceId);
}
void ResourceAllocator::checkwaitingProcess(){
    bool foundFreeR;
    bool foundAtAll;
    qDebug() << "-----------------------gadfss------------:";
    processWoutRIterator it = waitingProcesses.begin();
    while (it != waitingProcesses.end()) {
        foundAtAll=false;
        foundFreeR=false;
        for (resourceListIterator iter = resourceList.begin(); iter != resourceList.end(); ++iter){
            if (((*iter)->name == it->resource)&&(!((*iter)->inUse))){
                (*iter)->addToWaitingList(it->process);
                foundFreeR=true;
                break;
            }
        };

        if (!(foundFreeR)){
            for (resourceListIterator iter = resourceList.begin(); iter != resourceList.end(); ++iter){
                if ((*iter)->name == it->resource){
                    (*iter)->addToWaitingList(it->process);
                    foundAtAll=true;
                    break;
                }
            }
        };
        if ((foundAtAll)||(foundFreeR)){
            it = waitingProcesses.erase(it);
        }else {
            ++it;
        }

    }
}
